package com.gnss.mqutil.producer;

import com.gnss.common.proto.CommandProto;
import com.gnss.common.proto.LocationProto;
import com.gnss.common.proto.LocationProtoDTO;
import com.gnss.common.proto.MediaFileProtoDTO;
import com.gnss.common.proto.RpcProto;
import com.gnss.common.proto.TerminalProto;
import com.gnss.mqutil.constants.MqConstants;
import com.gnss.mqutil.converter.ProtobufMessageConverter;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitMessagingTemplate;
import org.springframework.amqp.rabbit.core.RabbitTemplate;

import java.util.UUID;

/**
 * @author guangbinhuang
 * @date 2018/4/13
 * @desc RabbitMQ消息发送
 **/
public class RabbitMessageSender {

    private RabbitTemplate rabbitTemplate;

    public RabbitMessageSender(RabbitTemplate rabbitTemplate) {
        rabbitTemplate.setMessageConverter(new ProtobufMessageConverter());
        RabbitMessagingTemplate rabbitMessagingTemplate = new RabbitMessagingTemplate();
        rabbitMessagingTemplate.setRabbitTemplate(rabbitTemplate);
        this.rabbitTemplate = rabbitTemplate;
    }

    /**
     * 发送位置信息
     * @param terminalProto
     * @param locationProto
     * @throws Exception
     */
    public void sendLocation(TerminalProto terminalProto, LocationProto locationProto) throws Exception {
        LocationProtoDTO locationProtoDto = new LocationProtoDTO();
        locationProtoDto.setLocationProto(locationProto);
        locationProtoDto.setTerminalProto(terminalProto);
        String routingKey = String.format("%d.location", terminalProto.getTerminalId());
        rabbitTemplate.convertAndSend(MqConstants.LOCATION_EXCHANGE, routingKey, locationProtoDto);
    }

    /**
     * 发送状态和位置
     * @param terminalProto
     * @param locationProto
     * @throws Exception
     */
    public void sendStatusAndLocation(TerminalProto terminalProto, LocationProto locationProto) throws Exception {
        LocationProtoDTO locationProtoDto = new LocationProtoDTO();
        locationProtoDto.setLocationProto(locationProto);
        locationProtoDto.setTerminalProto(terminalProto);
        String locationRoutingKey = String.format("%d.location", terminalProto.getTerminalId());
        rabbitTemplate.convertAndSend(MqConstants.LOCATION_EXCHANGE, locationRoutingKey, locationProtoDto);
        String statusRoutingKey = String.format("%d.status", terminalProto.getTerminalId());
        rabbitTemplate.convertAndSend(MqConstants.STATUS_EXCHANGE, statusRoutingKey, locationProtoDto);
    }

    /**
     * 发送多媒体文件
     * @param mediaFileDto
     * @throws Exception
     */
    public void sendMediaFile(MediaFileProtoDTO mediaFileDto) throws Exception {
        String routingKey = String.format("%d.media.file", mediaFileDto.getTerminalInfo().getTerminalId());
        rabbitTemplate.convertAndSend(MqConstants.MEDIA_FILE_EXCHANGE, routingKey, mediaFileDto);
    }

    /**
     * 发送下行指令
     * @param commandProto
     * @throws Exception
     */
    public void sendDownCommand(CommandProto commandProto) throws Exception {
        String nodeName = commandProto.getToNode();
        String routingKey = String.format("%d.%s.down.command", commandProto.getTerminalId(), nodeName);
        rabbitTemplate.convertAndSend(MqConstants.DOWN_COMMAND_EXCHANGE, routingKey, commandProto);
    }

    /**
     * 发送上行指令
     * @param commandProto
     * @throws Exception
     */
    public void sendUpCommand(CommandProto commandProto) throws Exception {
        String nodeName = commandProto.getFromNode();
        String routingKey = String.format("%d.%s.up.command", commandProto.getTerminalId(), nodeName);
        rabbitTemplate.convertAndSend(MqConstants.UP_COMMAND_EXCHANGE, routingKey, commandProto);
    }

    /**
     * 发送RPC请求
     * @param rpcProto
     * @return
     * @throws Exception
     */
    public RpcProto sendAndReceive(RpcProto rpcProto) throws Exception {
        CorrelationData correlationId = new CorrelationData(UUID.randomUUID().toString());
        Object response = rabbitTemplate.convertSendAndReceive(MqConstants.RPC_EXCHANGE, MqConstants.RPC_ROUTING_KEY, rpcProto, correlationId);
        return (RpcProto) response;
    }
}